﻿using System;
using System.Collections.Generic;
using RentalSystem.Data.EF.Core;
using System.Data.Common;

namespace RentalSystem.Data.EF.Dao
{
    public class EFAgenciesDao : IAgenciesDao
    {
        #region Queries

        private readonly string GetByIdQuery;
        private readonly string ListQuery;
        private readonly string GetIdByNameQuery;
        private readonly string GetByFileQuery;

        #endregion

        private EFManager<Agencies> manager;

        public EFAgenciesDao(RentalDatabaseEntities repository)
        {
            ListQuery = "SELECT VALUE a FROM Agencies AS a;";
            GetByIdQuery = "SELECT VALUE a FROM Agencies AS a WHERE a.AgencyID = @Id;";
            GetIdByNameQuery = "SELECT a.AgencyID FROM Agencies AS a WHERE a.AgencyName = @Name;";
            GetByFileQuery = "SELECT a.AgencyID FROM Agencies AS a WHERE a.AgencyImageFileID = @FileId;";
            
            this.manager = new EFManager<Agencies>(repository);
        }

        #region IDao1Key

        public Agencies Add(Agencies entity)
        {
            manager.Database.AddToAgencies(entity);
            manager.Save();
            return entity;
        }

        public Agencies Get(int id)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@Id", id)
                };

            var agencies = manager.SQLQueryToEntity(GetByIdQuery, parameters);

            foreach (Agencies agency in agencies)
            {
                return agency;
            }

            return null;
        }

        public void Delete(int id)
        {
            manager.Database.Agencies.DeleteObject(Get(id));
            manager.Save();
        }

        public void Delete(Agencies entity)
        {
            manager.Database.Agencies.DeleteObject(entity);
            manager.Save();
        }

        public void Update(Agencies entity, uint fields)
        {
            Agencies fromDb = Get(entity.AgencyID);

            if (fromDb != null)
            {
                if ((fields & (uint)AgencyFields.Address) == (uint)AgencyFields.Address)
                    fromDb.AgencyAddress = entity.AgencyAddress;
                if ((fields & (uint)AgencyFields.AgencyType) == (uint)AgencyFields.AgencyType)
                    fromDb.AgencyTypes = entity.AgencyTypes;
                if ((fields & (uint)AgencyFields.City) == (uint)AgencyFields.City)
                    fromDb.AgencyCity = entity.AgencyCity;
                if ((fields & (uint)AgencyFields.CreatedDate) == (uint)AgencyFields.CreatedDate)
                    fromDb.AgencyCreatedDate = entity.AgencyCreatedDate;
                if ((fields & (uint)AgencyFields.IsActive) == (uint)AgencyFields.IsActive)
                    fromDb.AgencyIsActive = entity.AgencyIsActive;
                if ((fields & (uint)AgencyFields.Name) == (uint)AgencyFields.Name)
                    fromDb.AgencyName = entity.AgencyName;
                if ((fields & (uint)AgencyFields.ZipCode) == (uint)AgencyFields.ZipCode)
                    fromDb.AgencyZipCode = entity.AgencyZipCode;
                if ((fields & (uint)AgencyFields.ImageFile) == (uint)AgencyFields.ImageFile)
                    fromDb.AgencyImageFileID = entity.AgencyImageFileID;

                manager.Save();
            }
        }

        public List<Agencies> List()
        {
            List<Agencies> list = new List<Agencies>();

            var agencies = manager.SQLQueryToEntity(ListQuery);

            foreach (Agencies agency in agencies)
            {
                list.Add(agency);
            }

            return list;
        }

        #endregion

        public int GetIdByName(string name)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@Name", name)
                };

            var results = manager.SQLQuery(GetIdByNameQuery, parameters);

            foreach (DbDataRecord rec in results)
            {
                return Convert.ToInt32(rec[0]);
            }

            return -1;
        }
        
        public void DeleteAgencyImage(int fileId)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@FileId", fileId)
                };

            var agencies = manager.SQLQueryToEntity(GetByFileQuery, parameters);

            foreach (Agencies agency in agencies)
            {
                agency.Files = null;
            }

            manager.Save();
        }
    }
}
